package com.mdc.mansion.core.modules.order.impl;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.mdc.mansion.common.Md5RsaUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.http.HttpStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.esotericsoftware.minlog.Log;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mdc.mansion.common.exception.BusinessException;
import com.mdc.mansion.common.util.DateUtils;
import com.mdc.mansion.common.util.I18nUtil;
import com.mdc.mansion.common.util.SerialToolKit;
import com.mdc.mansion.common.util.StringUtils;
import com.mdc.mansion.common.util.math.MathUtils;
import com.mdc.mansion.core.common.restaurant.RestaurantCommon;
import com.mdc.mansion.core.common.util.AltoPayUtils;
import com.mdc.mansion.core.common.util.MapUtils;
import com.mdc.mansion.core.common.util.RestaurantSupport;
import com.mdc.mansion.core.common.util.UUIDGenerator;
import com.mdc.mansion.core.modules.basedata.PushMessageService;
import com.mdc.mansion.core.modules.dishes.RestaurantDishesComboService;
import com.mdc.mansion.core.modules.dishes.RestaurantDishesService;
import com.mdc.mansion.core.modules.dishes.RestaurantDishesStandardService;
import com.mdc.mansion.core.modules.dishes.dto.RestaurantDishesComboDTO;
import com.mdc.mansion.core.modules.dishes.dto.RestaurantDishesDTO;
import com.mdc.mansion.core.modules.order.RestaurantOrderComboItemService;
import com.mdc.mansion.core.modules.order.RestaurantOrderItemComboDetailService;
import com.mdc.mansion.core.modules.order.RestaurantOrderItemService;
import com.mdc.mansion.core.modules.order.RestaurantOrderService;
import com.mdc.mansion.core.modules.order.dto.RestaurantOrderItemDTO;
import com.mdc.mansion.core.modules.pay.RestaurantOrderPayBackService;
import com.mdc.mansion.core.modules.pay.RestaurantOrderPayRefundService;
import com.mdc.mansion.core.modules.pay.RestaurantOrderPayService;
import com.mdc.mansion.core.modules.pay.RestaurantOrderRefundBackService;
import com.mdc.mansion.core.modules.pay.RestaurantPayCfgService;
import com.mdc.mansion.core.modules.pay.dto.AltoPayCallResult;
import com.mdc.mansion.core.modules.pay.dto.AltoPayQryResult;
import com.mdc.mansion.core.modules.pay.dto.AltoPayResult;
import com.mdc.mansion.core.modules.pay.dto.AltoRefundCallResult;
import com.mdc.mansion.core.modules.pay.dto.AltoRefundQryResult;
import com.mdc.mansion.core.modules.pay.dto.AltoRefundResult;
import com.mdc.mansion.core.modules.pay.dto.AltoResult;
import com.mdc.mansion.core.modules.pay.mo.AltoPayCode;
import com.mdc.mansion.core.modules.pay.mo.AltoPayMo;
import com.mdc.mansion.core.modules.pay.mo.AltoPayQryMo;
import com.mdc.mansion.core.modules.pay.mo.AltoRefundMo;
import com.mdc.mansion.core.modules.restaurant.RestaurantTableService;
import com.mdc.mansion.dataaccess.common.context.ContextHolder;
import com.mdc.mansion.dataaccess.common.service.CrudService;
import com.mdc.mansion.dataaccess.modules.basedata.entity.PushMessage;
import com.mdc.mansion.dataaccess.modules.basedata.entity.RestaurantOrderDTO;
import com.mdc.mansion.dataaccess.modules.dishes.entity.RestaurantDishes;
import com.mdc.mansion.dataaccess.modules.dishes.entity.RestaurantDishesStandard;
import com.mdc.mansion.dataaccess.modules.order.dao.RestaurantOrderDao;
import com.mdc.mansion.dataaccess.modules.order.dao.RestaurantOrderItemDao;
import com.mdc.mansion.dataaccess.modules.order.entity.RestaurantOrder;
import com.mdc.mansion.dataaccess.modules.order.entity.RestaurantOrderComboItem;
import com.mdc.mansion.dataaccess.modules.order.entity.RestaurantOrderItem;
import com.mdc.mansion.dataaccess.modules.order.entity.RestaurantOrderItemComboDetail;
import com.mdc.mansion.dataaccess.modules.order.mo.RestaurantHisUnionMo;
import com.mdc.mansion.dataaccess.modules.order.mo.RestaurantOderItemUnionMo;
import com.mdc.mansion.dataaccess.modules.order.mo.RestaurantOrderItemMO;
import com.mdc.mansion.dataaccess.modules.order.vo.RestaurantOrderItemVo;
import com.mdc.mansion.dataaccess.modules.order.vo.RestaurantOrderVo;
import com.mdc.mansion.dataaccess.modules.pay.entity.RestaurantOrderPay;
import com.mdc.mansion.dataaccess.modules.pay.entity.RestaurantOrderPayBack;
import com.mdc.mansion.dataaccess.modules.pay.entity.RestaurantOrderPayRefund;
import com.mdc.mansion.dataaccess.modules.pay.entity.RestaurantOrderRefundBack;
import com.mdc.mansion.dataaccess.modules.pay.entity.RestaurantPayCfg;
import com.mdc.mansion.dataaccess.modules.restaurant.entity.Restaurant;
import com.mdc.mansion.dataaccess.modules.restaurant.entity.RestaurantTable;
import com.mdc.mansion.dataaccess.modules.restaurant.vo.RestaurantTableVo;
import com.mdc.mansion.dataaccess.modules.system.entity.User;


/**
 * 餐厅订单信息ServiceImpl
 * @author mingdongc
 * @version 2018-01-01
 */
@Service
public class RestaurantOrderServiceImpl extends CrudService<RestaurantOrderDao, RestaurantOrder> implements RestaurantOrderService {
    private final static Logger logger = LoggerFactory.getLogger(RestaurantOrderServiceImpl.class);

    @Autowired
    private RestaurantDishesService restaurantDishesService;

    @Autowired
    private RestaurantDishesComboService restaurantDishesComboService;

    @Autowired
    private RestaurantOrderItemService restaurantOrderItemService;

    @Autowired
    private RestaurantOrderComboItemService restaurantOrderComboItemService;

    @Autowired
    private RestaurantDishesStandardService restaurantDishesStandardService;

    @Autowired
    private PushMessageService pushMessageService;

	@Autowired
	private RestaurantTableService restaurantTableService;

	@Autowired
	private RestaurantOrderItemComboDetailService restaurantOrderItemComboDetailService;
	
	@Autowired
	private RestaurantOrderItemDao restaurantOrderItemDao;
	
	@Autowired
    private RestaurantPayCfgService restaurantPayCfgService;
	
	@Autowired
    private RestaurantOrderPayService restaurantOrderPayService;
	
	@Autowired
	private RestaurantOrderPayRefundService restaurantOrderPayRefundService;
	
	@Autowired
	private RestaurantOrderPayBackService restaurantOrderPayBackService;
	
	@Autowired
    private RestaurantOrderRefundBackService restaurantOrderRefundBackService;
	
	private static final String encode = "UTF-8";
	
	
	
    /**
     * 提交订单
     * @param data
     */
    @Override
    @Transactional
    public void submit(String data) {
        JSONObject jsonObject=JSONObject.parseObject(data);
        String tableId=jsonObject.getString("restaurantTableId");
        JSONArray dishesList=jsonObject.getJSONArray("dishesList");
        JSONArray dishesComboList=jsonObject.getJSONArray("dishesComboList");
        if(StringUtils.isEmpty(tableId) || (CollectionUtils.isEmpty(dishesList) && CollectionUtils.isEmpty(dishesComboList))){
            throw new BusinessException(I18nUtil.getMessage("param.error"));// 参数错误
        }
        List<RestaurantDishesDTO> restaurantDishes=generateRestaurantDishes(dishesList);
        List<RestaurantDishesComboDTO> restaurantDishesComboDTOs=generateRestaurantDishesCombo(dishesComboList);

        RestaurantOrder restaurantOrder = this.findNotCheckOrderByTableId(tableId);
        if(restaurantOrder==null){
            createNewOrder(tableId,restaurantDishes,restaurantDishesComboDTOs);
        }else{
            orderAddItem(restaurantOrder,restaurantDishes,restaurantDishesComboDTOs);
        }
//        if(StringUtils.equals(ContextHolder.currentP(),"h5")){
//            List<String> tags =Lists.newArrayList();
//            RestaurantTable restaurantTable = restaurantTableService.get(tableId);
//            if(restaurantTable!=null){
//                pushMessageService.pushBusinessMessage(PushMessage.BUSINESS_TYPE.USER_CALL.getVal(),restaurantTable.getChineseName(),"");
//            }
//        }
    }

    private RestaurantOrder findNotCheckOrderByTableId(String tableId) {
        return this.dao.findNotCheckOrderByTableId(tableId,RestaurantCommon.RestaurantSave);
    }

    @Override
    @Transactional
    public void urgent(String data) {
        JSONObject jsonObject=JSONObject.parseObject(data);
        String id=jsonObject.getString("id");
        RestaurantOrder restaurantOrder = this.get(id);
        if(restaurantOrder!=null){
        	RestaurantTable restaurantTable = restaurantTableService.get(restaurantOrder.getRestaurantTableId());
            if(restaurantTable!=null){
                pushMessageService.pushBusinessMessage(PushMessage.BUSINESS_TYPE.USER_URGE.getVal(),restaurantTable.getChineseName(),"");
            }
        }
    }

    /**
     * 2018年3月5日 16:21:09 对订单数据进行汇总
     * 汇总条件: 订单、套餐、状态、规格、口味
     * 有一个不一样则新的记录
     *  汇总实现方式改变, 数据库汇总之后再读取对应的ITEM ID
     *  
     */
    @Override
    public Map<String,Object> getNotCheckOutOrderItems(String data) {
    	Map<String,Object> paraMap = Maps.newHashMap();
    	paraMap.put("restaurantId",ContextHolder.currentRestaurant().getId());
        RestaurantOrderItemDTO dto= null;
        List<RestaurantOderItemUnionMo> dishesList = null;
        RestaurantOrder orderInfo = null;
        Map<String,Object> returnMap = Maps.newHashMap();

        String restaurantOrderId = "";
        if(StringUtils.isNotEmpty(data)){
            JSONObject jsonObject=JSONObject.parseObject(data);
            String restaurantTableId=jsonObject.getString("restaurantTableId");
            if(StringUtils.isNotBlank(restaurantTableId)){paraMap.put("restaurantTableId",restaurantTableId);}
        }
        List<RestaurantOrderItemMO>  restaurantOrderItemMOs=restaurantOrderItemService.getMergeDishes(paraMap);
        List<RestaurantOrderItemDTO> restaurantOrderItemDTOs=Lists.newArrayList();
        if(CollectionUtils.isNotEmpty(restaurantOrderItemMOs))
        {
        	for(RestaurantOrderItemMO mo:restaurantOrderItemMOs){
        		paraMap = new HashMap<String,Object>();
        		dto=new RestaurantOrderItemDTO();
        		BeanUtils.copyProperties(mo,dto);
        		paraMap.put("restaurantId", mo.getRestaurantId());
        		paraMap.put("restaurantOrderId", mo.getRestaurantOrderId());
        		paraMap.put("restaurantDishesComboId", mo.getRestaurantDishesComboId());
                paraMap.put("restaurantDishesId",mo.getRestaurantDishesId());
        		paraMap.put("dishesStatus", mo.getDishesStatus());
        		paraMap.put("restaurantDishesStandardId", mo.getRestaurantDishesStandardId());
        		paraMap.put("restaurantDishesFlavorId", mo.getRestaurantDishesFlavorId());
                List<String> idList = restaurantOrderItemService.getItemListForMerge(paraMap);
        		dto.setItemList(idList);
                dto.setCreateDate(mo.getCreateTime());
        		dto.setId(dto.getItemList().get(0));
        		restaurantOrderId = mo.getRestaurantOrderId();
        		restaurantOrderItemDTOs.add(dto);
        	}
            /**
             * 打印重新调用，根据orderId 调取数据
             */
            paraMap = Maps.newConcurrentMap();
            paraMap.put("restaurantOrderId", restaurantOrderId);
            paraMap.put("restaurantId", ContextHolder.currentRestaurant().getId());
            dishesList = restaurantOrderItemDao.findCheckOutList(paraMap);
            orderInfo = this.dao.get(restaurantOrderId);
            returnMap.put("totalPrice",orderInfo.getTotalPrice());
            returnMap.put("abatement",orderInfo.getAbatement().add(orderInfo.getTotalPrice().subtract(orderInfo.getTotalDiscountPrice())));
            returnMap.put("servicePrice",orderInfo.getServicePrice());
            returnMap.put("actualReceivePrice",orderInfo.getActualReceivePrice());
            returnMap.put("refundPrice",orderInfo.getRefundPrice());
            returnMap.put("tradeNo",orderInfo.getTradeNo());
            returnMap.put("notifyUrl",this.getNotifyUrl(restaurantOrderId,orderInfo.getTradeNo()));
        }
        returnMap.put("dishesOrderItemList", restaurantOrderItemDTOs);
        returnMap.put("itemDetailList", dishesList);
        
        return returnMap;
    }
    
    private Object getNotifyUrl(String restaurantOrderId, String tradeNo) {
        RestaurantOrderPay orderPay = new RestaurantOrderPay();
        orderPay.setOutTradeNo(restaurantOrderId);
        orderPay.setTradeNo(tradeNo);
        orderPay = restaurantOrderPayService.get(orderPay);
        if(null == orderPay){
            return null;
        }
        return orderPay.getNotifyUrl();
    }
    
    @Override
    @Transactional
    public void cancel(String data) {
        if(StringUtils.isBlank(data)){
            throw new BusinessException(I18nUtil.getMessage("param.error"));// 参数错误
        }
        User currentOperationUser = RestaurantSupport.getCurrentOperationUser();
        String[] idArray=net.sf.json.JSONObject.fromObject(data).getString("id").split(":");
        for(String id:idArray)
        {
        	RestaurantOrderItem restaurantOrderItem = restaurantOrderItemService.get(id);
            if(restaurantOrderItem==null){return;}
            /**菜品撤销进行状态校验，状态为2,3的不能撤销**/
            if(RestaurantCommon.RestaurantOrderDishesStatusStep2 == restaurantOrderItem.getDishesStatus()
            		|| RestaurantCommon.RestaurantOrderDishesStatusStep3 == restaurantOrderItem.getDishesStatus() )
            {
            	/****菜品正在制作，不能撤销***/
            	throw new BusinessException(I18nUtil.getMessage("order.dishes.status.error"));// 参数错误

            }
            restaurantOrderItem = new RestaurantOrderItem();
            restaurantOrderItem.setId(id);
            restaurantOrderItem.setUpdateBy(currentOperationUser);
            restaurantOrderItem.setUpdateTime(Calendar.getInstance().getTime());
            restaurantOrderItem.setDishesStatus(RestaurantOrderItem.DISHES_STATUS.CANCEL.getVal());
            restaurantOrderItemService.updateSelective(restaurantOrderItem);
            
            /***套餐不为空则代表是套餐订单,需处理***/
            if(StringUtils.isNotBlank(restaurantOrderItem.getRestaurantDishesComboId()) && (!("-1".equals(restaurantOrderItem.getRestaurantDishesComboId()))))
            {
            	RestaurantOrderComboItem restaurantOrderComboItem = new RestaurantOrderComboItem();
            	restaurantOrderComboItem.setRestaurantOrderItemId(restaurantOrderItem.getId());
            	restaurantOrderComboItem.setRestaurantDishesComboId(restaurantOrderItem.getRestaurantDishesComboId());
            	List<RestaurantOrderComboItem> comboList =  restaurantOrderComboItemService.findList(restaurantOrderComboItem);
            	if(!(null == comboList || 0 == comboList.size()))
            	{
            		for(RestaurantOrderComboItem combo:comboList)
            		{
            			 /**菜品撤销进行状态校验，状态为2,3的不能撤销**/
                        if(RestaurantCommon.RestaurantOrderDishesStatusStep2 == combo.getDishesStatus()
                        		|| RestaurantCommon.RestaurantOrderDishesStatusStep3 == combo.getDishesStatus() )
                        {
                        	/****菜品正在制作，不能撤销***/
                        	throw new BusinessException(I18nUtil.getMessage("order.dishes.status.error"));// 参数错误
                        }
            			
            			RestaurantOrderComboItem comboDetail = new RestaurantOrderComboItem();
            			comboDetail.setId(combo.getId());
            			comboDetail.setUpdateBy(currentOperationUser);
            			comboDetail.setUpdateTime(Calendar.getInstance().getTime());
            			comboDetail.setDishesStatus(RestaurantOrderItem.DISHES_STATUS.CANCEL.getVal());
            			restaurantOrderComboItemService.updateSelective(comboDetail);
            		}
            	}
            }
        }
    }

    @Override
    @Transactional
    public void orderAddItem(String data) {
        JSONObject jsonObject=JSONObject.parseObject(data);
        String restaurantOrderId=jsonObject.getString("restaurantOrderId");
        JSONArray dishesList=jsonObject.getJSONArray("dishesList");
        JSONArray dishesComboList=jsonObject.getJSONArray("dishesComboList");
        if(StringUtils.isEmpty(restaurantOrderId) || (CollectionUtils.isEmpty(dishesList) && CollectionUtils.isEmpty(dishesComboList))){
            throw new BusinessException(I18nUtil.getMessage("param.error"));// 参数错误
        }
        RestaurantOrder restaurantOrder = this.get(restaurantOrderId);
        if(restaurantOrder==null || restaurantOrder.getOrderStatus()==RestaurantOrder.ORDER_STATUS.CHECK_OUT.getVal()){
            throw new BusinessException(I18nUtil.getMessage("param.error"));}

        List<RestaurantDishesDTO> restaurantDishes=generateRestaurantDishes(dishesList);
        List<RestaurantDishesComboDTO> restaurantDishesComboDTOs=generateRestaurantDishesCombo(dishesComboList);
        orderAddItem(restaurantOrder,restaurantDishes,restaurantDishesComboDTOs);
    }

    @Transactional
    protected void orderAddItem(RestaurantOrder restaurantOrder, List<RestaurantDishesDTO> restaurantDishes, List<RestaurantDishesComboDTO> restaurantDishesComboDTOs) {
        List<RestaurantOrderItem> restaurantOrderItems=Lists.newArrayList();
        String tableId = restaurantOrder.getRestaurantTableId();
        generateOrderItems(tableId, restaurantDishes, restaurantOrder, restaurantOrderItems);
        generateOrderComboItems(tableId, restaurantDishesComboDTOs, restaurantOrder, restaurantOrderItems);
        saveOrderItems(restaurantOrder, restaurantDishesComboDTOs, restaurantOrderItems, tableId);
        this.reCalculate(restaurantOrder);
    }

    @Transactional
    protected void saveOrderItems(RestaurantOrder restaurantOrder, List<RestaurantDishesComboDTO> restaurantDishesComboDTOs, List<RestaurantOrderItem> restaurantOrderItems, String tableId) {
        List<RestaurantOrderComboItem> restaurantOrderComboItems=Lists.newArrayList();
        for(RestaurantOrderItem orderItem:restaurantOrderItems){
            restaurantOrderItemService.save(orderItem);
            String dishesComboId = orderItem.getRestaurantDishesComboId();
            if(StringUtils.isBlank(dishesComboId)){continue;}
            generateOrderComboItems(tableId, restaurantDishesComboDTOs, restaurantOrder, restaurantOrderComboItems, orderItem, dishesComboId);
        }
        for(RestaurantOrderComboItem restaurantOrderComboItem:restaurantOrderComboItems){
            restaurantOrderComboItemService.save(restaurantOrderComboItem);
        }
    }
    
    /**
     * 订单金额结算
     * @param restaurantOrder
     */
    @Transactional
    protected void reCalculate(RestaurantOrder restaurantOrder) {
        RestaurantOrderItem restaurantOrderItem=new RestaurantOrderItem();
        restaurantOrderItem.setRestaurantOrderId(restaurantOrder.getId());
        List<RestaurantOrderItem> restaurantOrderItems = restaurantOrderItemService.findCanCalculateList(restaurantOrderItem);
        if(CollectionUtils.isEmpty(restaurantOrderItems)){return;}
        double totalDiscountPrice=0;
        
        if(CollectionUtils.isNotEmpty(restaurantOrderItems) && 0 != restaurantOrderItems.size()) {
            RestaurantOrderItem orderItemDetail = restaurantOrderItems.get(0);
            if(null != orderItemDetail)
            {
                restaurantOrder.setTotalPrice((null == orderItemDetail.getPrice())?(new BigDecimal("0")):orderItemDetail.getPrice());
                restaurantOrder.setTotalDiscountPrice((null == orderItemDetail.getDiscountPrice())?(new BigDecimal("0")):orderItemDetail.getDiscountPrice());
                totalDiscountPrice = Double.valueOf(StringUtils.isNotBlank(orderItemDetail.getDiscountPrice().toString())?orderItemDetail.getDiscountPrice().toString():"0");
            }else{
                restaurantOrder.setTotalPrice(new BigDecimal("0"));
                restaurantOrder.setTotalDiscountPrice(new BigDecimal("0"));
            }
        }
        
        restaurantOrder.setServicePrice(new BigDecimal(MathUtils.multiply(restaurantOrder.getServiceTariffing().doubleValue(),totalDiscountPrice)));
        BigDecimal rebate = restaurantOrder.getRebate();
        double subtract = MathUtils.subtract(totalDiscountPrice, restaurantOrder.getAbatement()!=null ?  restaurantOrder.getAbatement().doubleValue():0d);
        double multiply = MathUtils.multiply(subtract, MathUtils.divide(rebate!=null ? rebate.doubleValue() : 100, 100));
        double receivablePrice= MathUtils.add(multiply,restaurantOrder.getServicePrice().doubleValue());
        restaurantOrder.setReceivablePrice(new BigDecimal(receivablePrice));
        restaurantOrder.setUpdateBy(RestaurantSupport.getCurrentOperationUser());
        this.updateSelective(restaurantOrder);
    }

    @Transactional
    protected void createNewOrder(String tableId, List<RestaurantDishesDTO> restaurantDishes, List<RestaurantDishesComboDTO> restaurantDishesComboDTOs) {
       String serialNum=createSerialNum(ContextHolder.currentRestaurant().getId()); //创建流水号
        int billNo=1; //账单编号
        RestaurantOrder restaurantOrder = generateRestaurantOrder(tableId, restaurantDishes, restaurantDishesComboDTOs, serialNum, billNo);
        this.save(restaurantOrder);

        List<RestaurantOrderItem> restaurantOrderItems=Lists.newArrayList();
        generateOrderItems(tableId, restaurantDishes, restaurantOrder, restaurantOrderItems);
        generateOrderComboItems(tableId, restaurantDishesComboDTOs, restaurantOrder, restaurantOrderItems);
        saveOrderItems(restaurantOrder, restaurantDishesComboDTOs, restaurantOrderItems, tableId);
        this.reCalculate(restaurantOrder);
    }

    private void generateOrderComboItems(String tableId, List<RestaurantDishesComboDTO> restaurantDishesComboDTOs, RestaurantOrder restaurantOrder, List<RestaurantOrderComboItem> restaurantOrderComboItems, RestaurantOrderItem orderItem, String dishesComboId) {
        for(RestaurantDishesComboDTO restaurantDishesComboDTO:restaurantDishesComboDTOs){
            if(!StringUtils.equals(restaurantDishesComboDTO.getId(),dishesComboId)){continue;}
            for(RestaurantDishesDTO dishes:restaurantDishesComboDTO.getSelectRestaurantDishesList()){
                RestaurantOrderComboItem orderComboItem=new RestaurantOrderComboItem();
                orderComboItem.setRestaurantId(ContextHolder.currentRestaurant().getId());
                orderComboItem.setRestaurantOrderId(restaurantOrder.getId());
                orderComboItem.setRestaurantOrderItemId(orderItem.getId());
                orderComboItem.setRestaurantDishesComboId(orderItem.getRestaurantDishesComboId());
                orderComboItem.setOrderSerialNum(restaurantOrder.getSerialNum());
                orderComboItem.setRestaurantTableId(tableId);
                orderComboItem.setRestaurantDishesId(dishes.getId());
                orderComboItem.setRestaurantDishesFlavorId(dishes.getSelectDishesFlavorId());
                orderComboItem.setRestaurantDishesStandardId(dishes.getSelectDishesStandardId());
                orderComboItem.setAmount("1");
                orderComboItem.setPrice(dishes.getPrice());
                orderComboItem.setDiscountPrice(dishes.getDiscountPrice());
                orderComboItem.setDishesStatus(RestaurantOrderItem.DISHES_STATUS.TO_BE_CONFIRM.getVal());
                if(!StringUtils.equals(ContextHolder.currentP(),"h5")){
                    orderComboItem.setDishesStatus(RestaurantOrderItem.DISHES_STATUS.CONFIRMED.getVal());
                }
                restaurantOrderComboItems.add(orderComboItem);
            }
        }
    }

    private void generateOrderComboItems(String tableId, List<RestaurantDishesComboDTO> restaurantDishesComboDTOs, RestaurantOrder restaurantOrder, List<RestaurantOrderItem> restaurantOrderItems) {
        if(CollectionUtils.isNotEmpty(restaurantDishesComboDTOs)){
            for(RestaurantDishesComboDTO dishesComboDTO:restaurantDishesComboDTOs){
                RestaurantOrderItem restaurantOrderItem=new RestaurantOrderItem();
                restaurantOrderItem.setRestaurantId(ContextHolder.currentRestaurant().getId());
                restaurantOrderItem.setRestaurantOrderId(restaurantOrder.getId());
                restaurantOrderItem.setOrderSerialNum(restaurantOrder.getSerialNum());
                restaurantOrderItem.setRestaurantTableId(tableId);
                restaurantOrderItem.setRestaurantDishesComboId(dishesComboDTO.getId());
                restaurantOrderItem.setAmount(String.valueOf(dishesComboDTO.getSelectAmount()));
                restaurantOrderItem.setRestaurantStaffVerifyId(ContextHolder.currentLoginAccount());
                restaurantOrderItem.setPrice(new BigDecimal(MathUtils.multiply(dishesComboDTO.getSelectAmount(),dishesComboDTO.getPrice().doubleValue())));
                restaurantOrderItem.setDiscountPrice(new BigDecimal(MathUtils.multiply(dishesComboDTO.getSelectAmount(),dishesComboDTO.getDiscountPrice().doubleValue())));
                restaurantOrderItem.setDishesStatus(RestaurantOrderItem.DISHES_STATUS.TO_BE_CONFIRM.getVal());
                if(!StringUtils.equals(ContextHolder.currentP(),"h5")){
                    restaurantOrderItem.setDishesStatus(RestaurantOrderItem.DISHES_STATUS.CONFIRMED.getVal());
                }
                restaurantOrderItem.setCreateBy(RestaurantSupport.getCurrentOperationUser());
                restaurantOrderItem.setUpdateBy(RestaurantSupport.getCurrentOperationUser());
                restaurantOrderItems.add(restaurantOrderItem);
            }
        }
    }

    private void generateOrderItems(String tableId, List<RestaurantDishesDTO> restaurantDishes, RestaurantOrder restaurantOrder, List<RestaurantOrderItem> restaurantOrderItems) {
        if(CollectionUtils.isNotEmpty(restaurantDishes)){
            for(RestaurantDishesDTO restaurantDishesDTO:restaurantDishes){
                RestaurantOrderItem restaurantOrderItem=new RestaurantOrderItem();
                restaurantOrderItem.setRestaurantId(ContextHolder.currentRestaurant().getId());
                restaurantOrderItem.setRestaurantOrderId(restaurantOrder.getId());
                restaurantOrderItem.setRestaurantDishesStandardId(restaurantDishesDTO.getSelectDishesStandardId());
                restaurantOrderItem.setRestaurantDishesFlavorId(restaurantDishesDTO.getSelectDishesFlavorId());
                restaurantOrderItem.setOrderSerialNum(restaurantOrder.getSerialNum());
                restaurantOrderItem.setRestaurantTableId(tableId);
                restaurantOrderItem.setRestaurantStaffVerifyId(ContextHolder.currentLoginAccount());
                restaurantOrderItem.setRestaurantDishesId(restaurantDishesDTO.getId());
                restaurantOrderItem.setAmount(String.valueOf(restaurantDishesDTO.getSelectAmount()));
                restaurantOrderItem.setDishesStatus(RestaurantOrderItem.DISHES_STATUS.TO_BE_CONFIRM.getVal());
                if(!StringUtils.equals(ContextHolder.currentP(),"h5")){
                    restaurantOrderItem.setDishesStatus(RestaurantOrderItem.DISHES_STATUS.CONFIRMED.getVal());
                }
                restaurantOrderItem.setCreateBy(RestaurantSupport.getCurrentOperationUser());
                restaurantOrderItem.setUpdateBy(RestaurantSupport.getCurrentOperationUser());
                double price = restaurantDishesDTO.getPrice().doubleValue();
                double discountPrice = restaurantDishesDTO.getDiscountPrice().doubleValue();
                if(StringUtils.isNotBlank(restaurantDishesDTO.getSelectDishesStandardId())&&!"-1".equals(restaurantDishesDTO.getSelectDishesStandardId())){
                    restaurantOrderItem.setRestaurantDishesStandardId(restaurantDishesDTO.getSelectDishesStandardId());
                    RestaurantDishesStandard restaurantDishesStandard = restaurantDishesStandardService.get(restaurantDishesDTO.getSelectDishesStandardId());
                    if(restaurantDishesStandard==null){
                        throw new BusinessException(I18nUtil.getMessage("param.error"));// 参数错误
                    }
                    price = restaurantDishesStandard.getPrice().doubleValue();
                    discountPrice = restaurantDishesStandard.getDiscountPrice().doubleValue();
                }
                restaurantOrderItem.setPrice(new BigDecimal(MathUtils.multiply(restaurantDishesDTO.getSelectAmount().doubleValue(), price)));
                restaurantOrderItem.setDiscountPrice(new BigDecimal(MathUtils.multiply(restaurantDishesDTO.getSelectAmount().doubleValue(), discountPrice)));
                restaurantOrderItems.add(restaurantOrderItem);
            }
        }
    }

    private RestaurantOrder generateRestaurantOrder(String tableId, List<RestaurantDishesDTO> restaurantDishes, List<RestaurantDishesComboDTO> restaurantDishesComboDTOs, String serialNum, int billNo) {
        RestaurantOrder restaurantOrder=new RestaurantOrder();
        restaurantOrder.setRestaurantTableId(tableId);
        restaurantOrder.setRestaurantId(ContextHolder.currentRestaurant().getId());
        restaurantOrder.setSerialNum(serialNum);
        restaurantOrder.setBillNo(billNo);
        restaurantOrder.setServiceTariffing(ContextHolder.currentRestaurant().getServiceTariffing());
        restaurantOrder.setOrderStatus(RestaurantOrder.ORDER_STATUS.CUSTOMER_ORDER.getVal());
        if(!StringUtils.equals(ContextHolder.currentP(),"h5")){
            restaurantOrder.setOrderStatus(RestaurantOrder.ORDER_STATUS.WAITER_SURE.getVal());
        }
        restaurantOrder.setCreateBy(RestaurantSupport.getCurrentOperationUser());
        restaurantOrder.setUpdateBy(RestaurantSupport.getCurrentOperationUser());
        return restaurantOrder;
    }

    private String createSerialNum(String id) {
        synchronized (id){
            String serialNum= SerialToolKit.sequence();
            return serialNum;
        }
    }

    private List<RestaurantDishesComboDTO> generateRestaurantDishesCombo(JSONArray dishesComboList) {
        List<RestaurantDishesComboDTO> restaurantDishesComboDTOs=Lists.newArrayList();
        if(CollectionUtils.isNotEmpty(dishesComboList)){
            for(int i=0;i<dishesComboList.size();i++){
                JSONObject obj=dishesComboList.getJSONObject(i);
                String id=obj.getString("id");
                String dishesIds=obj.getString("dishesIds");
                int amount=obj.getIntValue("amount");
                RestaurantDishesComboDTO dishesComboDTO=restaurantDishesComboService.findById(id);
                if(dishesComboDTO==null ||
                        !dishesComboDTO.getRestaurantId().equals(ContextHolder.currentRestaurant().getId()) ||
                        StringUtils.isBlank(dishesIds)){
                    throw new BusinessException(I18nUtil.getMessage("param.error"));// 参数错误
                }
                dishesComboDTO.setSelectAmount(amount);
                String[] split = dishesIds.split(",");
                List<String> ids = Lists.newArrayList();
                Map<String,String> dishStandardMap =new HashMap<>();
                Map<String,String> dishFlavorMap =new HashMap<>();
                for(String ds:split){
                    String iid=ds.split(":")[0];
                    String dishesStandardId = ds.split(":")[1];
                    String dishesFlavorId=ds.split(":")[2];
                    dishStandardMap.put(iid,dishesStandardId);
                    dishFlavorMap.put(iid, dishesFlavorId);
                    ids.add(iid);
                }

                List<RestaurantDishes> selectRestaurantDishesList=restaurantDishesService.getListByIds(ids);
                if(CollectionUtils.isEmpty(selectRestaurantDishesList) || selectRestaurantDishesList.size()!=ids.size()){
                    throw new BusinessException(I18nUtil.getMessage("param.error"));// 参数错误
                }
                List<RestaurantDishesDTO> restaurantDishesDTOs=Lists.newArrayList();
                for(RestaurantDishes restaurantDishes:selectRestaurantDishesList){
                    if(restaurantDishes.getStockoutFlag()==1){
                        throw new BusinessException(I18nUtil.getMessage("dishes.stockout"));// 参数错误
                    }
                    RestaurantDishesDTO restaurantDishesDTO=new RestaurantDishesDTO();
                    BeanUtils.copyProperties(restaurantDishes,restaurantDishesDTO);
                    restaurantDishesDTO.setSelectDishesFlavorId(dishFlavorMap.get(restaurantDishes.getId()));
                    restaurantDishesDTO.setSelectDishesStandardId(dishStandardMap.get(restaurantDishes.getId()));
                    restaurantDishesDTOs.add(restaurantDishesDTO);
                }
                dishesComboDTO.setSelectRestaurantDishesList(restaurantDishesDTOs);
                restaurantDishesComboDTOs.add(dishesComboDTO);
            }
        }
        return restaurantDishesComboDTOs;
    }

    private List<RestaurantDishesDTO> generateRestaurantDishes(JSONArray dishesList) {
        List<RestaurantDishesDTO> restaurantDishesDTOs=Lists.newArrayList();
        if(CollectionUtils.isNotEmpty(dishesList)){
            for(int i=0;i<dishesList.size();i++){
                JSONObject obj=dishesList.getJSONObject(i);
                String id=obj.getString("id");
                String dishesStandardId=obj.getString("dishesStandardId");
                String dishesFlavorId=obj.getString("dishesFlavorId");
                double amount=obj.getDoubleValue("amount");
                RestaurantDishes dishes = restaurantDishesService.get(id);
                if(dishes==null || !dishes.getRestaurantId().equals(ContextHolder.currentRestaurant().getId())){
                    throw new BusinessException(I18nUtil.getMessage("param.error"));// 参数错误
                }
                if(dishes.getStockoutFlag()==1){
                    throw new BusinessException(I18nUtil.getMessage("dishes.stockout"));// 参数错误
                }
                RestaurantDishesDTO dishesDTO=new RestaurantDishesDTO();
                BeanUtils.copyProperties(dishes,dishesDTO);
                dishesDTO.setSelectDishesStandardId(dishesStandardId);
                dishesDTO.setSelectAmount(new BigDecimal(amount));
                dishesDTO.setSelectDishesFlavorId(dishesFlavorId);
                restaurantDishesDTOs.add(dishesDTO);
            }
        }
        return restaurantDishesDTOs;
    }

	/**
	 * 更改订单中的餐桌ID
	 * 逻辑
	 * 1、查询当前订单的信息使用的餐桌
	 * 2、对比更换餐桌和当前餐桌是否一致
	 * 3、查询要使用的餐桌是否在其他订单存在
	 * 4、更新订单 对应的餐桌
	 */
	@Transactional
	@Override
	public void changeTable(RestaurantOrder restaurantOrder) {
		String newTableId = null;
		String oldTableId = null;
		String restaurantId = null;
		List<RestaurantOrder> orderList = null;
		String orderId = null;

		try
		{
			newTableId = restaurantOrder.getRestaurantTableId();
			restaurantId = restaurantOrder.getRestaurantId();
			orderId = restaurantOrder.getId();

			restaurantOrder.setRestaurantTableId(null);
			///查询订单对应的
			orderList = this.findList(restaurantOrder);
			RestaurantOrder restaurantOrderTmp = orderList.get(0);
			if( restaurantOrderTmp == null)
			{
				/**订单不存在,请核实**/
				throw new BusinessException(I18nUtil.getMessage("order.table.null.exception"));
			}

			///核对新老桌号是否一致
			oldTableId = restaurantOrderTmp.getRestaurantTableId();
			if(newTableId.equals(oldTableId))
			{
				/**桌号一致,无需更新**/
				throw new BusinessException(I18nUtil.getMessage("order.table.same.exception"));
			}

			restaurantOrder = new RestaurantOrder();
			restaurantOrder.setRestaurantId(restaurantId);
			restaurantOrder.setRestaurantTableId(newTableId);
			/***存在服务员未确认的订单,不能更改***/
			restaurantOrder.setOrderStatus(RestaurantCommon.RestaurantOrderStatusStep0);
			restaurantOrder.setDelFlag(RestaurantCommon.RestaurantSave);
			orderList = this.findList(restaurantOrder);
			if(!( null == orderList || 0 ==orderList.size()))
			{
				/**新桌号存在订单,请确认桌号是否正确**/
				throw new BusinessException(I18nUtil.getMessage("order.table.exist.exception"));
			}

			/***存在已确认的订单,不能更改***/
			restaurantOrder.setOrderStatus(RestaurantCommon.RestaurantOrderStatusStep1);
			orderList = this.findList(restaurantOrder);
			if(!( null == orderList || 0 ==orderList.size()))
			{
				/**新桌号存在订单,请确认桌号是否正确**/
				throw new BusinessException(I18nUtil.getMessage("order.table.exist.exception"));
			}

			restaurantOrder = new RestaurantOrder();
			restaurantOrder.setId(orderId);
			restaurantOrder.setRestaurantTableId(newTableId);
			restaurantOrder.setUpdateTime(Calendar.getInstance().getTime());
			this.updateSelective(restaurantOrder);

			/****更新菜品 对应餐桌ID****/
			RestaurantOrderItem restaurantOrderItem = new RestaurantOrderItem();
			restaurantOrderItem.setRestaurantOrderId(orderId);
			List<RestaurantOrderItem> itemList = restaurantOrderItemService.findList(restaurantOrderItem);
			if(! (null == itemList || 0 == itemList.size()))
			{
				for(RestaurantOrderItem restaurantOrderItemTmp:itemList)
				{
					restaurantOrderItem = new RestaurantOrderItem();
					restaurantOrderItem.setId(restaurantOrderItemTmp.getId());
					restaurantOrderItem.setRestaurantTableId(newTableId);
					restaurantOrderItem.setUpdateTime(Calendar.getInstance().getTime());
					restaurantOrderItemService.updateSelective(restaurantOrderItem);
				}
			}

			/****更新套餐 对应餐桌ID****/
			RestaurantOrderComboItem restaurantOrderComboItem = new RestaurantOrderComboItem();
			restaurantOrderComboItem.setRestaurantOrderId(orderId);
			List<RestaurantOrderComboItem> comboItemList = restaurantOrderComboItemService.findList(restaurantOrderComboItem);
			if(! (null == comboItemList || 0 == comboItemList.size()))
			{
				for(RestaurantOrderComboItem restaurantOrderComboItemTmp:comboItemList)
				{
					restaurantOrderComboItem = new RestaurantOrderComboItem();
					restaurantOrderComboItem.setId(restaurantOrderComboItemTmp.getId());
					restaurantOrderComboItem.setRestaurantTableId(newTableId);
					restaurantOrderComboItem.setUpdateTime(Calendar.getInstance().getTime());
					restaurantOrderComboItemService.updateSelective(restaurantOrderComboItem);
				}
			}

		}catch(BusinessException e)
		{
			Log.error(e.getMessage());
			throw e;
		}
	}


	/**
	 * 结账使用
	 * 1、根据餐桌、订单号获取订单下菜品
	 * 2、对于有没有完成的菜品需提示是否退菜
	 * 3、根据菜品计算出整个账单金额及优惠金额
	 * 4、叠加服务费、打折等费用计算最终金额，根据页面计算更新数据库数据
	 *
	 *  新增对快餐/非快餐的判断,非快餐可直接查询及结算
	 *
	 * @
	 */
	@Override
	public Map<String, Object> queryByOrder(RestaurantOrderVo restaurantOrderVo)  {

		RestaurantOrder restaurantOrder = null;
		List<RestaurantOrder> orderList = null;
		Map<String,Object> itemMap = null;
		Map<String,Object> billOrderMap = new HashMap<String,Object>(256);
		try
		{
			restaurantOrder = new RestaurantOrder();
			BeanUtils.copyProperties (restaurantOrder,restaurantOrderVo);
			restaurantOrder.setId(restaurantOrderVo.getId());
			orderList = this.findList(restaurantOrderVo);
			if(null == orderList || 0 == orderList.size())
			{
				/**订单不存在，请核对**/
				throw new BusinessException(I18nUtil.getMessage("order.table.null.exception"));
			}

			restaurantOrder = orderList.get(0);

			itemMap = this.getItemList(restaurantOrder);

			billOrderMap = MapUtils.bean2map(restaurantOrder);
			billOrderMap.put("disList", itemMap.get("disOrderList"));

		}catch(BusinessException e)
		{
			Log.error(e.getMessage());
			throw e;
		}catch(Exception e)
		{
			/**结账失败,请联系客服**/
			Log.error(e.getMessage());
			throw new BusinessException(I18nUtil.getMessage("order.out.fail.exception"));
		}

		return billOrderMap;
	}


	/**
	 * 查询并组装订单中菜品数据
	 * @param restaurantOrder
	 * @return
	 */
	private Map<String,Object> getItemList(RestaurantOrder restaurantOrder) {
		RestaurantOrderItemVo restaurantOrderItemVo = null;
		RestaurantOrderItem restaurantOrderItem = null;
		List<RestaurantOrderItem> orderItemList = null;
		List<RestaurantOrderItemVo> orderItemReturnList = null;
		Map<String,Object> retrunMap = new 	HashMap<String,Object>(256);
		try
		{
			restaurantOrderItem = new RestaurantOrderItem();

			restaurantOrderItem.setRestaurantOrderId(restaurantOrder.getId());
			restaurantOrderItem.setDelFlag(RestaurantCommon.RestaurantSave);
			orderItemList = restaurantOrderItemService.findList(restaurantOrderItem);

			if(null == orderItemList || 0 == orderItemList.size())
			{
				/***本订单无任何菜品,请核对**/
				throw new BusinessException(I18nUtil.getMessage("order.null.dishes.exception"));
			}

			orderItemReturnList = new ArrayList<RestaurantOrderItemVo>();
			for(RestaurantOrderItem restaurantOrderItemTmp : orderItemList)
			{
				restaurantOrderItemVo = new RestaurantOrderItemVo();
				BeanUtils.copyProperties(restaurantOrderItemVo, restaurantOrderItemTmp);

				if(StringUtils.isNotBlank(restaurantOrderItemTmp.getRestaurantDishesComboId()))
				{
					////获取套餐子菜品的完成进度
					restaurantOrderItemVo.setOrderComboItemList(this.getComboItemList(restaurantOrderItemTmp));
				}
				orderItemReturnList.add(restaurantOrderItemVo);

			}
			retrunMap.put("disOrderList", orderItemReturnList);



		}catch(BusinessException e)
		{
			Log.error(e.getMessage());
			throw e;
		}catch(Exception e)
		{
			/**结账失败,请联系客服**/
			Log.error(e.getMessage());
			throw new BusinessException(I18nUtil.getMessage("order.dishes.status.exception"));
		}


		return retrunMap;
	}


	/**
	 * 获取订单中套餐子菜品的信息
	 * @param restaurantOrderItemTmp
	 * @return
	 */
	private List<RestaurantOrderComboItem> getComboItemList(RestaurantOrderItem restaurantOrderItemTmp) {
		RestaurantOrderComboItem restaurantOrderComboItem = null;
		List<RestaurantOrderComboItem> comboItemList = null;
		try {
			restaurantOrderComboItem = new RestaurantOrderComboItem();
			restaurantOrderComboItem.setRestaurantOrderId(restaurantOrderItemTmp.getRestaurantOrderId());
			comboItemList = restaurantOrderComboItemService.findList(restaurantOrderComboItem);
			if(null == comboItemList || 0 == comboItemList.size())
			{
				return null;
			}

		}catch(BusinessException e)
		{
			Log.error(e.getMessage());
			throw e;
		}catch(Exception e)
		{
			/**结账失败,请联系客服**/
			Log.error(e.getMessage());
			throw new BusinessException(I18nUtil.getMessage("order.dishes.status.exception"));
		}
		return comboItemList;
	}


	/**
	 * 结账使用
	 * 新增对快餐/非快餐的判断,非快餐可直接查询及结算
	 * 结账处理: 2018年2月9日 11:56:40 调整
	 * 结账不对菜品做状态处理
	 */
	@Transactional
	@Override
	public Map<String, Object> billCheckOut(RestaurantOrder restaurantOrder) {
		RestaurantOrderItem restaurantOrderItem = null;
		List<RestaurantOrderItem> orderDisList = null;
		RestaurantOrder restaurantOrderTmp = null;
        Map<String,Object> restaurantOrderItemDTOs = new HashMap<String,Object>();
		try{
			restaurantOrderTmp = new RestaurantOrder();
			restaurantOrderTmp.setId(restaurantOrder.getId());
			restaurantOrderTmp = this.get(restaurantOrder.getId());
			if(null == restaurantOrderTmp) {
				/**订单不存在，请核对**/
				throw new BusinessException(I18nUtil.getMessage("order.table.null.exception"));
			}
			restaurantOrderItem = new RestaurantOrderItem();
			restaurantOrderItem.setRestaurantOrderId(restaurantOrder.getId());
			restaurantOrderItem.setRestaurantId(restaurantOrder.getRestaurantId() );
			restaurantOrderItem.setRestaurantTableId(restaurantOrder.getRestaurantTableId());
			orderDisList = restaurantOrderItemService.findList(restaurantOrderItem);
			if(CollectionUtils.isEmpty(orderDisList)){
				/***本订单无任何菜品,请核对**/
				throw new BusinessException(I18nUtil.getMessage("order.null.dishes.exception"));
			}
			/****2018年2月9日 11:59:37 对菜品状态不做处理****/
//			for(RestaurantOrderItem restaurantOrderItemTmp : orderDisList) {
//				restaurantOrderItemTmp.setUpdateBy(restaurantOrder.getUpdateBy());
//				restaurantOrderItemTmp.setDishesStatus(RestaurantCommon.RestaurantOrderDishesStatusStep3);
//				restaurantOrderItemTmp.setUpdateTime(Calendar.getInstance().getTime());
//				if(StringUtils.isNotBlank(restaurantOrderItemTmp.getRestaurantDishesComboId())){
//					this.updateComboItem(restaurantOrderItemTmp);
//				}
//				restaurantOrderItem.setId(restaurantOrderItemTmp.getId());
//				restaurantOrderItem.setUpdateBy(restaurantOrder.getUpdateBy());
//				restaurantOrderItem.setUpdateTime(Calendar.getInstance().getTime());
//				restaurantOrderItemService.updateSelective(restaurantOrderItem);
//			}
            ///备注,,结账人员帐号
            if(StringUtils.isBlank(restaurantOrder.getRestaurantStaffCashierId())){
                restaurantOrder.setRestaurantStaffCashierId(StringUtils.isBlank(RestaurantSupport.getCurrentOperationUser().getLoginName())?RestaurantSupport.getCurrentOperationUser().getName():RestaurantSupport.getCurrentOperationUser().getLoginName());
            }
            if(null == restaurantOrder.getActualReceivePrice() || 0 == (new BigDecimal("0")).compareTo(restaurantOrder.getActualReceivePrice())){
                restaurantOrder.setActualReceivePrice(restaurantOrder.getReceivablePrice());
            }
//			restaurantOrder.setUpdateBy(RestaurantSupport.getCurrentOperationUser());
            restaurantOrder.setUpdateTime(Calendar.getInstance().getTime());
			restaurantOrder.setCashierTime(Calendar.getInstance().getTime());
            restaurantOrder.setOrderStatus(RestaurantCommon.RestaurantOrderStatusStep2);
			this.updateSelective(restaurantOrder);
            
            /**
             * 打印重新调用，根据orderId 调取数据
             */
            Map<String,Object> paraMap = new HashMap<String,Object>();
            paraMap.put("restaurantOrderId", restaurantOrder.getId());
            paraMap.put("restaurantId", ContextHolder.currentRestaurant().getId());
            List<RestaurantOderItemUnionMo> dishesList = restaurantOrderItemDao.findCheckOutList(paraMap);
            restaurantOrderItemDTOs.put("itemDetailList",dishesList);
            RestaurantOrder orderInfo = this.dao.get(restaurantOrder.getId());
            restaurantOrderItemDTOs.put("totalPrice",orderInfo.getTotalPrice());
            restaurantOrderItemDTOs.put("abatement",orderInfo.getAbatement().add(orderInfo.getTotalPrice().subtract(orderInfo.getTotalDiscountPrice())));
            restaurantOrderItemDTOs.put("servicePrice",orderInfo.getServicePrice());
            restaurantOrderItemDTOs.put("actualReceivePrice",orderInfo.getActualReceivePrice());
            restaurantOrderItemDTOs.put("refundPrice",orderInfo.getRefundPrice());
		}catch(BusinessException e)
		{
			Log.error(e.getMessage());
			throw e;
		}catch(Exception e)
		{
			/**结账失败,请联系客服**/
			Log.error(e.getMessage());
			throw new BusinessException(I18nUtil.getMessage("order.out.fail.exception"));
		}
		/*********  结账行为本身不发送消息，只有H5发起结账请求才发消息 by xizf
        String restaurantTableId = restaurantOrderTmp.getRestaurantTableId();
        List<String> tags =Lists.newArrayList();
        RestaurantTable restaurantTable = restaurantTableService.get(restaurantTableId);
        if(restaurantTable!=null){
            tags.add(restaurantOrderTmp.getRestaurantId()+ RestaurantStaff.ROLE_TYPE.FWY.getVal());
            tags.add(restaurantOrderTmp.getRestaurantId()+RestaurantStaff.ROLE_TYPE.SYY.getVal());
            pushMessageService.pushTagNotifi(tags,restaurantTable.getChineseName()+"-用户结账");

        } ******/
		return restaurantOrderItemDTOs;
	}

	/**
	 * 更新套餐数据
	 * 查询套餐将数据进行更新重新写入
	 * @param restaurantOrderItemTmp
	 */
	@Transactional
    protected void updateComboItem(RestaurantOrderItem restaurantOrderItemTmp ) {
		RestaurantOrderComboItem restaurantOrderComboItem = null;
		List<RestaurantOrderComboItem> comboItemList = null;
		try
		{
			restaurantOrderComboItem = new RestaurantOrderComboItem();
			restaurantOrderComboItem.setRestaurantId(restaurantOrderItemTmp.getRestaurantId());
			restaurantOrderComboItem.setRestaurantTableId(restaurantOrderItemTmp.getRestaurantTableId());
			restaurantOrderComboItem.setRestaurantOrderId(restaurantOrderItemTmp.getRestaurantOrderId());
			comboItemList = restaurantOrderComboItemService.findList(restaurantOrderComboItem);
			if(!(null == comboItemList ||  0 == comboItemList.size()))
			{
				for(RestaurantOrderComboItem restaurantOrderComboItemTmp : comboItemList)
				{
					restaurantOrderComboItemTmp.setDishesStatus(RestaurantCommon.RestaurantOrderDishesStatusStep3);
					restaurantOrderComboItemTmp.setUpdateBy(restaurantOrderItemTmp.getUpdateBy());
					restaurantOrderComboItemTmp.setUpdateTime(Calendar.getInstance().getTime());
					restaurantOrderComboItemService.update(restaurantOrderComboItemTmp);
				}
			}


		}catch(BusinessException e)
		{
			Log.error(e.getMessage());
			throw e;
		}catch(Exception e)
		{
			/**结账失败,请联系客服**/

			Log.error(e.getMessage());
			throw new BusinessException(I18nUtil.getMessage("order.out.fail.exception"));
		}

	}


	/**
	 * 退款处理I
	 * 入参: 餐厅ID，订单ID，退款金额
	 * 验证条件: 订单查询是否存在，对订单退款金额处理
	 *
	 */
	@Transactional
	@Override
	public void refund(RestaurantOrder restaurantOrder)  {
		RestaurantOrder restaurantOrderTmp = null;
		try
		{

			if(null == restaurantOrder.getRefundPrice() || restaurantOrder.getRefundPrice().compareTo(BigDecimal.ZERO) == 0)
			{
				/***退款金额为0，无法退款***/
				throw new BusinessException(I18nUtil.getMessage("order.refund.price.zero.exception"));
			}
            
            restaurantOrderTmp = new RestaurantOrder();
            restaurantOrderTmp.setSerialNum(restaurantOrder.getSerialNum());
            List<RestaurantOrder> list = findList(restaurantOrderTmp);
            restaurantOrderTmp = (RestaurantOrder)list.get(0);
			if(null == restaurantOrderTmp)
			{
				/***退款异常,请核对订单***/
				throw new BusinessException(I18nUtil.getMessage("order.refund.fail.exception"));
			}

			if( RestaurantCommon.RestaurantOrderStatusStep2 != restaurantOrderTmp.getOrderStatus())
			{
				/***本订单未结账,无法退款***/
				throw new BusinessException(I18nUtil.getMessage("order.refund.status.error.exception"));
			}

			if(restaurantOrderTmp.getRefundPrice().compareTo(BigDecimal.ZERO) != 0)
			{
				/***已经退款,请勿重复操作***/
				throw new BusinessException(I18nUtil.getMessage("order.refund.complete.exception"));
			}
			
            restaurantOrder.setRestaurantId(null);
            restaurantOrder.setSerialNum(null);
            restaurantOrder.setActualReceivePrice(restaurantOrderTmp.getActualReceivePrice().subtract(restaurantOrder.getRefundPrice()));
            restaurantOrder.setId(restaurantOrderTmp.getId());
            restaurantOrder.setUpdateBy(restaurantOrder.getUpdateBy());
            restaurantOrder.setUpdateTime(Calendar.getInstance().getTime());
			this.updateSelective(restaurantOrder);
   
		}catch(BusinessException e)
		{
			Log.error(e.getMessage());
			throw e;
		}catch(Exception e)
		{
			/**结账失败,请联系客服**/
			throw new BusinessException(I18nUtil.getMessage("order.refund.fail.exception"));
		}

	}



	/**
	 * 历史账单查询功能
	 * 只需查询到菜品级别，无需查询套餐明细
	 * 1、查询前一天收入总金额
	 * 2、查询当天收入总金额
	 * 3、查询每个餐桌就餐订单数据
	 * 4、查询每个 订单菜品数据
	 *
	 */
	@Override
	public Map<String, Object> history(RestaurantOrderVo restaurantOrderVo)  {
		List <Map<String,Object>> resultList = null;
		List <Map<String,Object>> orderList = null;
		Map<String, Object> returnMap = new HashMap<String, Object>(256);
		try
		{
			//获取查询当天收入及优惠情况
            resultList = querySumByDate(restaurantOrderVo.getRestaurantId(), restaurantOrderVo.getQueryDate());

			//获取查询当天的所有订单情况
            orderList = queryOrderList(restaurantOrderVo);
            
            returnMap.putAll((Map)resultList.get(0));
            returnMap.put("menuHistoryList", orderList);

		}catch(BusinessException e)
		{
			Log.error(e.getMessage());
			throw e;
		}catch(Exception e)
		{
			/**结账失败,请联系客服**/
			Log.error(e.getMessage());
			throw new BusinessException(I18nUtil.getMessage("order.history.fail.exception"));
		}
		return returnMap;
	}


	/**
	 * 查询某个餐厅/日期的订单情况
	 * 查询条件
	 * @param restaurantOrderVo
	 * @return
	 */
	private List<Map<String,Object>> queryOrderList(RestaurantOrderVo restaurantOrderVo) {
		Map<String,Object> parameterMap = new HashMap<String,Object>(256);
		List<Map <String ,Object>> retrunOrderList = new ArrayList<Map <String ,Object>>();
		List<RestaurantHisUnionMo> retrunItemList = null;
		Map <String ,Object> resultMap = new HashMap<String ,Object> ();
		RestaurantTable restaurantTable = new RestaurantTable();
        
        int start = 0;
        start = (Integer.parseInt(restaurantOrderVo.getPageNo()) - 1) * Integer.parseInt(restaurantOrderVo.getPageSize());
        parameterMap.put("restaurantId", restaurantOrderVo.getRestaurantId());
        parameterMap.put("queryDate", restaurantOrderVo.getQueryDate());
        parameterMap.put("start", Integer.valueOf(start));
        parameterMap.put("pageSize", Integer.valueOf(Integer.parseInt(restaurantOrderVo.getPageSize())));

		try{
			List<RestaurantOrder> reultList = this.dao.findOrderDayList(parameterMap);

			if(null == reultList || 0 == reultList.size())
			{
				return null;
			}

			for(RestaurantOrder restaurantOrder : reultList)
			{
				retrunItemList = this.findOrderItemList(restaurantOrder);
				resultMap = new HashMap<String ,Object> ();
				resultMap = MapUtils.objectToMap( restaurantOrder);
				restaurantTable.setId(restaurantOrder.getRestaurantTableId());
				resultMap.remove("tableNum");
				resultMap.put("tableNum",restaurantTableService.findList(restaurantTable).get(0).getNum());
				resultMap.remove("tableName");
				resultMap.put("tableName",restaurantTableService.findList(restaurantTable).get(0).getName());
				resultMap.put("cashierTime", restaurantOrder.getCashierTime());
				resultMap.remove("createBy");
				resultMap.put("createBy", restaurantOrder.getCreateBy().getId());
				resultMap.put("dishesList", retrunItemList);
				resultMap.put("price", restaurantOrder.getTotalPrice());
				resultMap.put("discountPrice", restaurantOrder.getTotalDiscountPrice());
				
                resultMap.put("totalPrice",restaurantOrder.getTotalPrice());
                resultMap.put("abatement",restaurantOrder.getAbatement().add(restaurantOrder.getTotalPrice().subtract(restaurantOrder.getTotalDiscountPrice())));
                resultMap.put("servicePrice",restaurantOrder.getServicePrice());
                resultMap.put("actualSeceivePrice",restaurantOrder.getActualReceivePrice());
                resultMap.put("refundPrice",restaurantOrder.getRefundPrice());
                
                resultMap.put("restaurantStaffCashierId",restaurantOrder.getRestaurantStaffCashierId());
				retrunOrderList.add(resultMap);

			}

		}catch(BusinessException e)
		{
			Log.error(e.getMessage());
			throw e;
		}catch(Exception e)
		{
//
			/**获取历史订单异常**/
			Log.error(e.getMessage());
			throw new BusinessException(I18nUtil.getMessage("order.history.fail.exception"));
		}

		return retrunOrderList;
	}

	/**
	 * 查询订单对应的菜品
	 * 参数: 餐厅,订单ID,流水号
	 * @param restaurantOrder
	 * @return
	 */
	private List<RestaurantHisUnionMo> findOrderItemList(RestaurantOrder restaurantOrder) {
		Map<String,String> parameterMap = Maps.newConcurrentMap();
		List<RestaurantHisUnionMo> hisInfoList = null;
		try{
			parameterMap.put("restaurantId", restaurantOrder.getRestaurantId());
			parameterMap.put("restaurantOrderId", restaurantOrder.getId());
			hisInfoList = restaurantOrderItemDao.getHisOrderInfo(parameterMap);
		}catch(Exception e)
		{
			e.printStackTrace();
			Log.error(e.getMessage());
			throw new BusinessException(I18nUtil.getMessage("order.history.fail.exception"));
		}
		return hisInfoList;
	}


	/**
	 * 查询查询当天和前一天的收入情况
	 * @param restaurantId
	 * @param queryDate
	 * @return
	 */
	private List <Map<String,Object>> querySumByDate(String restaurantId, String queryDate) {

		Map<String,Object> parameterMap = new HashMap<String,Object>(256);
		Map<String,Object> sumMap =  null;
		List <Map<String,Object>> resultList = null;
		try{
            parameterMap.put("restaurantId", restaurantId);
            parameterMap.put("queryDate", queryDate);
			

			resultList= this.dao.queryHistory(parameterMap);

			if(null == resultList || 0 == resultList.size() || null == resultList.get(0) )
			{
				resultList  = new ArrayList<Map<String,Object>>();
				sumMap = new HashMap<String,Object>(256);
				sumMap.put("orderDate", queryDate);
//				sumMap.put("createTime", "");
                sumMap.put("totalPrice", "0.00");
                sumMap.put("totalDiscountPrice", "0.00");
                sumMap.put("receivablePrice", "0.00");
                sumMap.put("actualReceivePrice", "0.00");
                sumMap.put("refundPrice", "0.00");
				resultList.add(sumMap);
			}
		}catch(Exception e)
		{
			Log.error(e.getMessage());
			throw new BusinessException(I18nUtil.getMessage("order.history.fail.exception"));
		}
		return resultList;
	}

	/**
	 * 获取餐厅订单列表,可分页
	 */
	@Override
	public List<RestaurantTableVo> getOrderStatusList(Restaurant restaurant, String pageSize, String pageNo){
		String queryDate = null;
		Calendar c = Calendar.getInstance();
		String restaurantId = null;
		List <RestaurantTableVo> orderList = null;
		try
		{
			/***添加参数处理****/
			if(StringUtils.isBlank(pageNo) || "0".equals(pageNo))
			{
				pageNo = "1";
			}

			int start = 0;
			start = ((Integer.parseInt(pageNo) -1)  * Integer.parseInt(pageSize)) ;
			restaurantId = restaurant.getId();

			queryDate = DateUtils.formatShortDate(c.getTime());
			orderList = this.dao.getOrderStatusList(restaurantId,queryDate,Integer.parseInt(pageSize),start);


		}catch(Exception e)
		{
			/**查询订单状态列表失败**/
			Log.error(e.getMessage());
			throw new BusinessException(I18nUtil.getMessage("order.status.list.fail.exception"));
		}

		return orderList;
	}

	/**
	 * 订单撤销流程
	 * 需判断角色，并更新订单和菜品的状态
	 * 从用户login_account 获取角色情况
	 * 
	 */
	@Transactional
	@Override
	public void orderCancel(String data,String userType) {
        if(StringUtils.isBlank(data)){
            throw new BusinessException(I18nUtil.getMessage("param.error"));// 参数错误
        }
        User currentOperationUser = RestaurantSupport.getCurrentOperationUser();
        if( null == currentOperationUser)
        {
        	currentOperationUser = new User();
        }
        currentOperationUser.setUserType(userType);
        
        if(!( RestaurantCommon.UserTypeAdmin.equals(userType) || RestaurantCommon.UserTypeFwy.equals(userType) 
        		|| RestaurantCommon.UserTypeSyy.equals(userType)))
        {
        	throw new BusinessException(I18nUtil.getMessage("order.cancel.role.exception"));
        }

    	String id=net.sf.json.JSONObject.fromObject(data).getString("id");
        RestaurantOrder restaurantOrder = this.get(id);
        if(restaurantOrder==null){return;}

        /****不管是否管理员还是服务员均将菜品进行取消操作****/
        this.cancelOrderDishes(restaurantOrder,currentOperationUser, null, RestaurantCommon.RestaurantOrderStatusStep3);

        /***管理员才能更新订单的状态为撤销***/
    	if(RestaurantCommon.UserTypeAdmin.equals(userType) )
        {
            ///更新订单状态
            restaurantOrder = new RestaurantOrder();
            restaurantOrder.setId(id);
            restaurantOrder.setUpdateBy(currentOperationUser);
            restaurantOrder.setOrderStatus(RestaurantCommon.RestaurantOrderStatusStep3);
            restaurantOrder.setUpdateTime(Calendar.getInstance().getTime());
            this.updateSelective(restaurantOrder);
        }

    	/****服务员时,如果订单状态为未确认，则删除该订单****/
    	if(RestaurantCommon.UserTypeFwy.equals(userType) || RestaurantCommon.UserTypeSyy.equals(userType))
        {
    		////删除订单及订单下的菜品
            RestaurantOrder restaurantOrderTmp = this.get(id);

            /***状态为0则表示订单无人确认,可以删除**/
    		if(restaurantOrderTmp.getOrderStatus() == RestaurantCommon.RestaurantOrderStatusStep0)
    		{
    			restaurantOrder = new RestaurantOrder();
        		restaurantOrder.setId(restaurantOrderTmp.getId());
        		restaurantOrder.setOrderStatus(RestaurantCommon.RestaurantOrderStatusStep3);
        		restaurantOrder.setDelFlag(RestaurantCommon.RestaurantDelete);
        		this.updateSelective(restaurantOrder);

        		/****服务员的撤销删除菜品***/
        		this.cancelOrderDishes(restaurantOrder,currentOperationUser,RestaurantCommon.RestaurantDelete,999);

    		}

        }

    	/*** 订单金额核算****/
    	this.reCalculate(this.get(restaurantOrder.getId()));

	}

	/**
	 * 具体更新处理
	 * 对管理员和
	 * @param restaurantOrder
	 * @param currentOperationUser
	 */
	@Transactional
    protected void cancelOrderDishes(RestaurantOrder restaurantOrder, User currentOperationUser, String deleteFlag,int orderStatus) {
    	List<RestaurantOrderItem> itemList = null;
    	List<RestaurantOrderItemComboDetail> comboItemList = null;
    	RestaurantOrderItemComboDetail restaurantOrderItemComboDetail = null;
    	RestaurantOrderItem restaurantOrderItem = null;

    	restaurantOrderItem = new RestaurantOrderItem();
        restaurantOrderItem.setRestaurantOrderId(restaurantOrder.getId());
        if(RestaurantCommon.UserTypeFwy.equals(currentOperationUser.getUserType()) || RestaurantCommon.UserTypeSyy.equals(currentOperationUser.getUserType()))
        {
        	/***服务员或收银员则限定只能更新状态为0的菜品***/
        	restaurantOrderItem.setDishesStatus(RestaurantCommon.RestaurantOrderDishesStatusStep0);
        }

    	 ////更新菜品的状态
        itemList = restaurantOrderItemService.findList(restaurantOrderItem);
        if(!( null == itemList || 0 == itemList.size()))
        {
        	for(RestaurantOrderItem  restaurantOrderItemTmp:itemList)
        	{
        		 restaurantOrderItem.setId(restaurantOrderItemTmp.getId());
        		 restaurantOrderItem.setUpdateBy(currentOperationUser);

        		 ////状态为3,代表为管理员撤销
        		 if(RestaurantCommon.RestaurantOrderStatusStep3 == orderStatus)
        		 {
        			 restaurantOrderItem.setDishesStatus(RestaurantCommon.RestaurantOrderDishesStatusStep5);
        		 }else//否则对菜品进行删除操作
        		 {
        			 restaurantOrderItem.setDelFlag(RestaurantCommon.RestaurantDelete);
        		 }

                 restaurantOrderItem.setUpdateTime(Calendar.getInstance().getTime());
                 restaurantOrderItemService.updateSelective(restaurantOrderItem);
        	}
        }

        ////更新套餐子菜品的状态
        restaurantOrderItemComboDetail = new RestaurantOrderItemComboDetail();
        restaurantOrderItemComboDetail.setRestaurantOrderId(restaurantOrder.getId());
        if(RestaurantCommon.UserTypeFwy.equals(currentOperationUser.getUserType()) || RestaurantCommon.UserTypeSyy.equals(currentOperationUser.getUserType()))
        {
        	/***服务员或收银员则限定只能更新状态为0的菜品***/
        	restaurantOrderItemComboDetail.setDishesStatus(RestaurantCommon.RestaurantOrderDishesStatusStep0);
        }
        comboItemList = restaurantOrderItemComboDetailService.findList(restaurantOrderItemComboDetail);
        if(!( null == itemList || 0 == itemList.size()))
        {
        	for(RestaurantOrderItemComboDetail  restaurantOrderItemComboDetailTmp:comboItemList)
        	{
                restaurantOrderItemComboDetail.setUpdateBy(currentOperationUser);
                restaurantOrderItemComboDetail.setId(restaurantOrderItemComboDetailTmp.getId());

	       		 ////状态为3,代表为管理员撤销
	       		 if(RestaurantCommon.RestaurantOrderStatusStep3 == orderStatus)
	       		 {
	       			restaurantOrderItemComboDetail.setDishesStatus(RestaurantCommon.RestaurantOrderDishesStatusStep5);
	       		 }else//否则对菜品进行删除操作
	       		 {
	       			restaurantOrderItemComboDetail.setDelFlag(RestaurantCommon.RestaurantDelete);
	       		 }
                restaurantOrderItemComboDetail.setUpdateTime(Calendar.getInstance().getTime());
                restaurantOrderItemComboDetailService.updateSelective(restaurantOrderItemComboDetail);
        	}
        }

	}

	/**
	 * 2018年3月8日 15:42:15 对接口进行调整,前端新传入价格和优惠价格，以便于反写ITEM表
	 */
	@Override
    @Transactional
    public void affirm(String data) {
        if(StringUtils.isBlank(data)){
            throw new BusinessException(I18nUtil.getMessage("param.error"));// 参数错误
        }
        JSONObject jsonObject=JSONObject.parseObject(data);
        String restaurantOrderId = jsonObject.getString("restaurantOrderId");
        String remark=jsonObject.getString("remark");
        JSONArray orderItems = jsonObject.getJSONArray("orderItems");
        if(StringUtils.isBlank(restaurantOrderId) || orderItems==null || orderItems.size()<=0){
            throw new BusinessException(I18nUtil.getMessage("param.error"));// 参数错误
        }
        List<String> orderItemIds=Lists.newArrayList();
        Map<String,String> amounts= Maps.newHashMap();
        
        for(int i=0;i<orderItems.size();i++){
            JSONObject jsonObject1 = orderItems.getJSONObject(i);
            orderItemIds.add(jsonObject1.getString("restaurantOrderItemId"));
            String price = jsonObject1.containsKey("price")?jsonObject1.getString("price"):"0";
            String discountPrice = jsonObject1.containsKey("discountPrice")?jsonObject1.getString("discountPrice"):"0";
            amounts.put(jsonObject1.getString("restaurantOrderItemId"),jsonObject1.getString("amount")+":"+price+":"+discountPrice);
        }
        RestaurantOrder restaurantOrder = this.get(restaurantOrderId);
        if(restaurantOrder==null ||
                restaurantOrder.getOrderStatus()==RestaurantOrder.ORDER_STATUS.REVOCATION.getVal() ||
                restaurantOrder.getOrderStatus()==RestaurantOrder.ORDER_STATUS.CHECK_OUT.getVal()){
            throw new BusinessException(I18nUtil.getMessage("param.error"));// 参数错误
        }
        String rk = restaurantOrder.getRemark();
        if(StringUtils.isNotBlank(rk)){rk=rk+"<br/>";}
        if(StringUtils.isNotBlank(remark)){restaurantOrder.setRemark(rk+remark);}
        restaurantOrder.setOrderStatus(RestaurantOrder.ORDER_STATUS.WAITER_SURE.getVal());
        restaurantOrder.setUpdateBy(RestaurantSupport.getCurrentOperationUser());
        this.updateSelective(restaurantOrder);
        
        ////处理菜品
        RestaurantOrderItemMO restaurantOrderItemMO=new RestaurantOrderItemMO();
        restaurantOrderItemMO.setRestaurantOrderId(restaurantOrderId);
        restaurantOrderItemMO.setRestaurantId(ContextHolder.currentRestaurant().getId());
        List<RestaurantOrderItemMO> list=restaurantOrderItemService.getNotWaiterSureOrderItems(restaurantOrderItemMO);
        if(CollectionUtils.isEmpty(list)){return;}
        this.changeMayBeRevocationOrderItem(list,orderItemIds);
        this.changeMayBeWaiterSureOrderItem(list,orderItemIds,amounts);
        this.reCalculate(restaurantOrder);
    }

    @Transactional
    protected void changeMayBeRevocationOrderItem(List<RestaurantOrderItemMO> list, List<String> orderItemIds) {
        List<RestaurantOrderItemMO> mayBeRevocationOrderItems=Lists.newArrayList();
        for(RestaurantOrderItemMO mo:list){
            if(!orderItemIds.contains(mo.getId())){mayBeRevocationOrderItems.add(mo);}
        }
        if(CollectionUtils.isEmpty(mayBeRevocationOrderItems)){return;}
        for(RestaurantOrderItemMO mo:mayBeRevocationOrderItems){
            RestaurantOrderItem orderItem=new RestaurantOrderItem();
            BeanUtils.copyProperties(mo,orderItem);
            orderItem.setDishesStatus(RestaurantOrderItem.DISHES_STATUS.CANCEL.getVal());
            orderItem.setUpdateBy(RestaurantSupport.getCurrentOperationUser());
//            orderItem.setRestaurantStaffVerifyId("7caeae7c29684719a74957e548ee801c");
            orderItem.setRestaurantStaffVerifyId(ContextHolder.currentRestaurantStaff().getId());
            restaurantOrderItemService.updateSelective(orderItem);
            if(StringUtils.isNotBlank(orderItem.getRestaurantDishesComboId())){
                RestaurantOrderItemComboDetail entity = new RestaurantOrderItemComboDetail();
                entity.setRestaurantDishesComboId(orderItem.getRestaurantDishesComboId());
                entity.setRestaurantOrderId(orderItem.getRestaurantOrderId());
                entity.setRestaurantOrderItemId(orderItem.getId());
                List<RestaurantOrderItemComboDetail> restaurantOrderItemComboDetails = restaurantOrderItemComboDetailService.findList(entity);
                if(CollectionUtils.isEmpty(restaurantOrderItemComboDetails)){continue;}
                for(RestaurantOrderItemComboDetail detail:restaurantOrderItemComboDetails){
                    detail.setDishesStatus(RestaurantOrderItem.DISHES_STATUS.CANCEL.getVal());
                    detail.setUpdateBy(RestaurantSupport.getCurrentOperationUser());
                    detail.setRestaurantStaffVerifyId(ContextHolder.currentRestaurantStaff().getId());
//                    orderItem.setRestaurantStaffVerifyId("7caeae7c29684719a74957e548ee801c");
                    restaurantOrderItemComboDetailService.updateSelective(detail);
                }
            }
        }
    }

    /**
     * 新增对价格及优惠价格的计算
     * @param list
     * @param orderItemIds
     * @param amounts
     */
    @Transactional
    protected void changeMayBeWaiterSureOrderItem(List<RestaurantOrderItemMO> list, List<String> orderItemIds,Map<String,String> amounts) {
        List<RestaurantOrderItemMO> mayBeWaiterSureOrderItems=Lists.newArrayList();
        for(RestaurantOrderItemMO mo:list){
            if(orderItemIds.contains(mo.getId())){mayBeWaiterSureOrderItems.add(mo);}
        }
        if(CollectionUtils.isEmpty(mayBeWaiterSureOrderItems)){return;}
        for(RestaurantOrderItemMO mo:mayBeWaiterSureOrderItems){
            RestaurantOrderItem orderItem=new RestaurantOrderItem();
            BeanUtils.copyProperties(mo,orderItem);
            String[] amountArray =  amounts.get(mo.getId()).split(":");
            orderItem.setDishesStatus(RestaurantOrderItem.DISHES_STATUS.CONFIRMED.getVal());
            orderItem.setUpdateBy(RestaurantSupport.getCurrentOperationUser());
            orderItem.setAmount(String.valueOf(amountArray[0]));
            orderItem.setPrice(new BigDecimal(amountArray[0]).multiply(new BigDecimal(amountArray[1])));
            orderItem.setDiscountPrice(new BigDecimal(amountArray[0]).multiply(new BigDecimal(amountArray[2])));
            orderItem.setRestaurantStaffVerifyId(ContextHolder.currentRestaurantStaff().getId());
//            orderItem.setRestaurantStaffVerifyId("7caeae7c29684719a74957e548ee801c");
            restaurantOrderItemService.updateSelective(orderItem);
            if(StringUtils.isNotBlank(orderItem.getRestaurantDishesComboId())){
                RestaurantOrderItemComboDetail entity = new RestaurantOrderItemComboDetail();
                entity.setRestaurantDishesComboId(orderItem.getRestaurantDishesComboId());
                entity.setRestaurantOrderId(orderItem.getRestaurantOrderId());
                entity.setRestaurantOrderItemId(orderItem.getId());
                List<RestaurantOrderItemComboDetail> restaurantOrderItemComboDetails = restaurantOrderItemComboDetailService.findList(entity);
                if(CollectionUtils.isEmpty(restaurantOrderItemComboDetails)){continue;}
                for(RestaurantOrderItemComboDetail detail:restaurantOrderItemComboDetails){
                    detail.setDishesStatus(RestaurantOrderItem.DISHES_STATUS.CONFIRMED.getVal());
                    detail.setUpdateBy(RestaurantSupport.getCurrentOperationUser());
                    detail.setRestaurantStaffVerifyId(ContextHolder.currentRestaurantStaff().getId());
                    restaurantOrderItemComboDetailService.updateSelective(detail);
                }
            }
        }
    }

	@Override
	public List<Map<String, Object>> getTotalAmountList(Map<String, Object> parameterMap) {
		return this.dao.getTotalAmountList(parameterMap);
	}

	@Override
	public List<Map<String, Object>> getCategoryAmountList(Map<String, Object> parameterMap) {
		return this.dao.getCategoryAmountList(parameterMap);
	}

	@Override
	public List<Map<String, Object>> getDishesAmountList(Map<String, Object> parameterMap) {
		return this.dao.getDishesAmountList(parameterMap);
	}

	@Override
	public List<Map<String, Object>> getWaitersTotalMoney(Map<String, Object> parameterMap) {
		return this.dao.getWaitersTotalMoney(parameterMap);
	}

	@Override
	public List<Map<String, Object>> getCashierTotalMoney(Map<String, Object> parameterMap) {
		return this.dao.getCashierTotalMoney(parameterMap);
	}

	@Override
	public List<Map<String, Object>> getCancelDishesTotalMoney(Map<String, Object> parameterMap) {
		return this.dao.getCancelDishesTotalMoney(parameterMap);
	}

	@Override
	public List<Map<String, Object>> getCancelOrderTotalMoney(Map<String, Object> parameterMap) {
		return this.dao.getCancelOrderTotalMoney(parameterMap);
	}

	@Override
	public List<Map<String, Object>> getTotalAmountListByMonth(Map<String, Object> parameterMap) {
		return this.dao.getTotalAmountListByMonth(parameterMap);
	}

	@Override
	public List<Map<String, Object>> getTotalAmountListByYear(Map<String, Object> parameterMap) {
		return this.dao.getTotalAmountListByYear(parameterMap);
	}

	@Override
	public List<RestaurantOrderDTO> findrestaurantCount(RestaurantOrderDTO restaurantOrderDTO) {
		return this.dao.findrestaurantCount(restaurantOrderDTO);
	}

	@Override
	public List<RestaurantOrderDTO> findStaffCount(RestaurantOrderDTO restaurantOrderDTO) {
		return this.dao.findStaffCount(restaurantOrderDTO);
	}

	@Override
	public List<RestaurantOrderDTO> findOrderCount(RestaurantOrderDTO restaurantOrderDTO) {
		return this.dao.findOrderCount(restaurantOrderDTO);
	}

	@Override
	public List<RestaurantOrderDTO> getTotalAmountList(RestaurantOrderDTO restaurantOrderDTO) {
		return this.dao.getTotalAmountListByOne(restaurantOrderDTO);
	}

	@Override
	public List<RestaurantOrderDTO> getCategoryAmountList(RestaurantOrderDTO restaurantOrderDTO) {
		return this.dao.getCategoryAmountListByOne(restaurantOrderDTO);
	}

	@Override
	public List<RestaurantOrderDTO> getDishesAmountList(RestaurantOrderDTO restaurantOrderDTO) {
		return this.dao.getDishesAmountListByOne(restaurantOrderDTO);
	}
    
    @Override
    public List<Map<String, Object>> getTotalAmountListByAllYear(Map<String, Object> parameterMap) {
        return this.dao.getTotalAmountListByAllYear(parameterMap);
    }
    
    
    /**
     * 查询订单信息,并组成调用支付参数
     * 查询店铺名称,并组装支付参数
     * @param restaurantOrder
     * @return
     */
    @Override
    public Map<String, Object> getPayJson(RestaurantOrder restaurantOrder) throws Exception {
        RestaurantPayCfg restaurantPayCfg = new RestaurantPayCfg();
        restaurantPayCfg.setRestaurantId(restaurantOrder.getRestaurantId());
        restaurantPayCfg.setIsPay("Y");
        restaurantPayCfg.setDelFlag("0");
        List<RestaurantPayCfg> payCfgList = restaurantPayCfgService.findList(restaurantPayCfg);
        if(null == payCfgList || 0 == payCfgList.size() )
        {
            logger.error("无支付配置信息，请确认商户开启线上支付");
        }
    
        RestaurantPayCfg payCfg = payCfgList.get(0);
        
        if(null == restaurantOrder.getActualReceivePrice() || 0 == (new BigDecimal("0")).compareTo(restaurantOrder.getActualReceivePrice())){
            restaurantOrder.setActualReceivePrice(restaurantOrder.getReceivablePrice());
        }
        
        AltoPayMo payMo = new AltoPayMo();
        payMo.setMch_id(payCfg.getMchId());
        payMo.setOut_trade_no(restaurantOrder.getId());
        payMo.setSubject(ContextHolder.currentRestaurant().getEnglishName());
        payMo.setAmount(restaurantOrder.getActualReceivePrice().toString());
        AltoResult result = AltoPayUtils.orderPay(payMo,payCfg);
        AltoPayResult payResult = (AltoPayResult)result.getResult();
        Map<String,Object> json = new HashMap<String,Object>();
        json.put("payUri",payResult.getUri());
        saveOrderPayLog(payResult,payMo);
        updateOrder(restaurantOrder,payResult);
        return json;
    }
    
    /**
     * 调用支付的时候先把所有参数记录到数据库,支付完成只修改订单状态既可
     * @param restaurantOrder
     * @param payResult
     */
    private void updateOrder(RestaurantOrder restaurantOrder, AltoPayResult payResult) {
        restaurantOrder.setPayFlag("1");
        restaurantOrder.setTradeNo(payResult.getTrade_no());
        restaurantOrder.setOrderStatus(RestaurantCommon.RestaurantOrderStatusStep1);
        this.updateSelective(restaurantOrder);
    }
    
    private void saveOrderPayLog(AltoPayResult result, AltoPayMo payMo) {
        RestaurantOrderPay restaurantOrderPay  = new RestaurantOrderPay();
        restaurantOrderPay.setRestaurantOrderId(payMo.getOut_trade_no());
        restaurantOrderPay.setMchId(payMo.getMch_id());
        restaurantOrderPay.setOutTradeNo(payMo.getOut_trade_no());
        restaurantOrderPay.setSubject(payMo.getSubject());
        restaurantOrderPay.setAmount(new BigDecimal(payMo.getAmount()));
        restaurantOrderPay.setCurrency(payMo.getCurrency());
        restaurantOrderPay.setOperatorId( ContextHolder.currentRestaurant().getUpdateBy().getName());
        restaurantOrderPay.setTradeType(payMo.getTrade_type());
        restaurantOrderPay.setTradeNo(result.getTrade_no());
        restaurantOrderPay.setPayUri(result.getUri());
        restaurantOrderPay.setPayStatus(AltoPayCode.DONE_PRE_PAY.getCode());
        restaurantOrderPay.setCreateBy(ContextHolder.currentRestaurant().getUpdateBy());
        restaurantOrderPayService.save(restaurantOrderPay);
    }
    
    /**
     * 支付回调
     * @param request
     * @param response
     */
    @Override
    public void OrderPayBack(HttpServletRequest request, HttpServletResponse response) throws IOException, ParseException {
        String data = request.getParameter("data");
        String sign = request.getParameter("sign");
        logger.error(">>>>>>>支付回调<<<<<<<:"+data);
        logger.error(">>>>>>>支付回调<<<<<<<:"+sign);

        AltoPayCallResult result =JSONObject.parseObject(data,AltoPayCallResult.class);
        RestaurantPayCfg payCfg = new RestaurantPayCfg();
        payCfg.setMchId(result.getMch_id());
        payCfg.setDelFlag("0");
        payCfg = this.getCfg(payCfg);
        AltoPayCallResult payResult = null;
        if(null == payCfg)
        {
            response.setStatus(HttpStatus.SC_BAD_REQUEST);
            response.getOutputStream().write("订单错误".getBytes("UTF-8"));
        }
        if( !Md5RsaUtils.verify(data,sign,payCfg.getPublicKey(),encode))
        {
            response.setStatus(HttpStatus.SC_BAD_REQUEST);
            response.getOutputStream().write(("支付回调签名验证失败订单号:"+result.getTrade_no()).getBytes("UTF-8"));
        }
        
        payResult = AltoPayUtils.orderPayCb(request,response,payCfg);
        /////更新请求记录和保存回调结果
        RestaurantOrderPay  orderPay = new RestaurantOrderPay();
        orderPay.setOutTradeNo(result.getOut_trade_no());
        orderPay.setPayStatus(AltoPayCode.DONE_PRE_PAY.getCode());
        List<RestaurantOrderPay> payOrderList = restaurantOrderPayService.findList(orderPay);
        if (null == payOrderList || 0 == payOrderList.size()) {
            this.updatePayLog(payOrderList.get(0),AltoPayCode.CALL_PRE_PAY_FAIL.getCode());
            response.setStatus(HttpStatus.SC_BAD_REQUEST);
            response.getOutputStream().write(("支付回调签名验证失败订单号:"+result.getTrade_no()).getBytes("UTF-8"));
        }
        
        RestaurantOrder order = this.get(payOrderList.get(0).getRestaurantOrderId());
        this.updatePayLog(payOrderList.get(0),AltoPayCode.CALL_PRE_PAY_SUCCESS.getCode());
        this.billCheckOut(order);
        this.savePayResult(payResult);
    }
    
    private void updatePayLog(RestaurantOrderPay restaurantOrderPay, String code) {
        restaurantOrderPay.setPayStatus(code);
        restaurantOrderPayService.updateSelective(restaurantOrderPay);
    }
    
    private void savePayResult(AltoPayCallResult payResult) throws ParseException {
        SimpleDateFormat format =  new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        RestaurantOrderPayBack payBack = new RestaurantOrderPayBack();
        payBack.setMchId(payResult.getMch_id());
        payBack.setOutTradeNo(payResult.getOut_trade_no());
        payBack.setTradeNo(payResult.getTrade_no());
        payBack.setAmount(new BigDecimal(payResult.getAmount()));
        payBack.setCurrency(payResult.getCurrency());
        payBack.setOperatorId(payResult.getOperator_id());
        payBack.setTradeStatus(Integer.valueOf(payResult.getTrade_status()));
        payBack.setPaytype(Integer.valueOf(payResult.getPaytype()));
        payBack.setFinishTime(format.parse(payResult.getFinish_time()));
        payBack.setCallTime(Calendar.getInstance().getTime());
        restaurantOrderPayBackService.save(payBack);
    }
    
    @Transactional
    @Override
    public void preRefundJson(RestaurantOrder restaurantOrder) throws Exception {
        String refundPrice = restaurantOrder.getRefundPrice().toString();
        restaurantOrder.setRefundPrice(null);
        restaurantOrder = this.findList(restaurantOrder).get(0);
        RestaurantPayCfg restaurantPayCfg = new RestaurantPayCfg();
        restaurantPayCfg.setRestaurantId(restaurantOrder.getRestaurantId());
        restaurantPayCfg.setIsPay("Y");
        restaurantPayCfg.setDelFlag("0");
        restaurantPayCfg = this.getCfg(restaurantPayCfg);
        if(null == restaurantPayCfg )
        {
            logger.error("无支付配置信息，请确认商户开启线上支付");
            throw new Exception("无支付配置信息，请确认商户开启线上支付!");
        }
        RestaurantOrderPay restaurantOrderPay = new RestaurantOrderPay();
        restaurantOrderPay.setOutTradeNo(restaurantOrder.getId());
        restaurantOrderPay.setDelFlag("0");
        restaurantOrderPay = restaurantOrderPayService.findList(restaurantOrderPay).get(0);
        ///校验退款金额是否正确
        AltoRefundMo altoRefundMo = new AltoRefundMo();
        altoRefundMo.setMch_id(restaurantPayCfg.getMchId());
        altoRefundMo.setOut_refund_no(UUIDGenerator.getUUID());
        altoRefundMo.setTrade_no(restaurantOrderPay.getTradeNo());
        altoRefundMo.setRefund_amount(refundPrice);
        altoRefundMo.setAmount(restaurantOrder.getActualReceivePrice().toString());
        altoRefundMo.setRefund_reason(RestaurantSupport.getCurrentOperationUser().getId()+"|"+RestaurantSupport.getCurrentOperationUser().getLoginName()+"|"+RestaurantSupport.getCurrentOperationUser().getName()+"|"+restaurantOrder.getId());
//        altoRefundMo.setNotify_url(refund_call_uri);
        AltoResult result =  AltoPayUtils.orderRefund(altoRefundMo,restaurantPayCfg);
        AltoRefundResult refundResult = (AltoRefundResult)result.getResult();
        ///保存退款日志
        this.saveRefundLog(restaurantOrder,altoRefundMo,restaurantPayCfg,restaurantOrderPay,refundResult);
        ////更新
        RestaurantOrder order = new RestaurantOrder();
        order.setId(restaurantOrder.getId());
        order.setUpdateBy(RestaurantSupport.getCurrentOperationUser());
        this.updateSelective(order);
    }
    
    @Transactional
    @Override
    public void OrderRefundBack(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String data = request.getParameter("data");
        String sign = request.getParameter("sign");
        logger.error(">>>>>>>退款回调<<<<<<<:"+data);
        logger.error(">>>>>>>退款回调<<<<<<<:"+request.getParameter("sign"));
        AltoRefundCallResult result =JSONObject.parseObject(data,AltoRefundCallResult.class);
        RestaurantPayCfg payCfg = new RestaurantPayCfg();
        payCfg.setMchId(result.getMch_id());
        payCfg.setDelFlag("0");
        payCfg = this.getCfg(payCfg);
        AltoRefundCallResult refundResult = null;
        if(null != payCfg)
        {
            refundResult = AltoPayUtils.orderRefundCb(request,response,payCfg);
        }
    
        if( !Md5RsaUtils.verify(data,sign,payCfg.getPublicKey(),encode))
        {
            response.setStatus(HttpStatus.SC_BAD_REQUEST);
            response.getOutputStream().write(("支付回调签名验证失败订单号:"+result.getOut_refund_no()).getBytes("UTF-8"));
        }
        
        /////更新请求记录和保存回调结果
        RestaurantOrderPayRefund orderRefund = new RestaurantOrderPayRefund();
        orderRefund.setMchId(result.getMch_id());
        orderRefund.setOutRefundNo(refundResult.getOut_refund_no());
        orderRefund.setOutTradeNo(refundResult.getOut_trade_no());
        orderRefund.setRefundStatus(AltoPayCode.DONE_PRE_REFUND.getCode());
        List<RestaurantOrderPayRefund> orderRefundList = restaurantOrderPayRefundService.findList(orderRefund);
        if (null == orderRefundList || 0 == orderRefundList.size()) {
            ////更新预支付状态
            this.updatePreRefund(orderRefund,AltoPayCode.CALL_PRE_REFUND_FAIL.getCode());
            response.setStatus(HttpStatus.SC_BAD_REQUEST);
            response.getOutputStream().write(("支付回调签名验证失败订单号:"+result.getOut_refund_no()).getBytes("UTF-8"));
        }
        orderRefund = orderRefundList.get(0);
        /////修改退款
        RestaurantOrder order = new RestaurantOrder();
        order.setId(orderRefund.getOutTradeNo());
        order.setRefundPrice(new BigDecimal(refundResult.getRefund_amount()));
        order.setActualReceivePrice(orderRefund.getAmount().subtract(new BigDecimal(refundResult.getRefund_amount())));
        ////更新订单状态
        this.updateSelective(order);
        ////更新预支付状态
        this.updatePreRefund(orderRefund,AltoPayCode.CALL_PRE_REFUND_SUCCESS.getCode());
        /////记录日志
        this.saveRefundResultLog(refundResult);
    }
    
    @Transactional
    protected void updatePreRefund(RestaurantOrderPayRefund orderRefund,String refundStatus) {
        orderRefund.setRefundStatus(refundStatus);
        restaurantOrderPayRefundService.updateSelective(orderRefund);
    }
    
    @Transactional
    protected RestaurantPayCfg getCfg(RestaurantPayCfg payCfg) {
        List<RestaurantPayCfg> cfgList =  restaurantPayCfgService.findList(payCfg);
        if(null == cfgList || 0 == cfgList.size())
        {
            return null;
        }
        return cfgList.get(0);
    }
    
    @Transactional
    protected void saveRefundResultLog(AltoRefundCallResult result) {
        RestaurantOrderRefundBack refundResult = new RestaurantOrderRefundBack();
        refundResult.setMchId(result.getMch_id());
        refundResult.setOutTradeNo(result.getOut_trade_no());
        refundResult.setOutRefundNo(result.getOut_refund_no());
        refundResult.setRefundAmount(new BigDecimal(result.getRefund_amount()));
        refundResult.setCurrency(result.getCurrency());
        refundResult.setRefundStatus(Integer.valueOf(result.getRefund_status()));
        restaurantOrderRefundBackService.save(refundResult);
    }
    
    /**
     * 日志保存
     * @param restaurantOrder
     * @param altoRefundMo
     * @param payCfg
     * @param restaurantOrderPay
     * @param refundResult
     */
    @Transactional
    protected void saveRefundLog(RestaurantOrder restaurantOrder, AltoRefundMo altoRefundMo, RestaurantPayCfg payCfg, RestaurantOrderPay restaurantOrderPay, AltoRefundResult refundResult) {
        RestaurantOrderPayRefund refund = new RestaurantOrderPayRefund();
        refund.setRestaurantOrderId(restaurantOrder.getId());
        refund.setMchId(payCfg.getMchId());
        refund.setOutTradeNo(restaurantOrderPay.getOutTradeNo());
        refund.setTradeNo(restaurantOrderPay.getTradeNo());
        refund.setOutRefundNo(altoRefundMo.getOut_refund_no());
        refund.setAmount(restaurantOrderPay.getAmount());
        refund.setRefundAmount(restaurantOrder.getRefundPrice());
        refund.setRefundReason("客户退款");
        refund.setResult(Integer.valueOf(refundResult.getResult()));
        if(!"0".equals(refundResult.getCode()))
        {
            refund.setErrCode(refundResult.getCode());
            refund.setErrMsg(refundResult.getErr());
        }
        refund.setRefundStatus(AltoPayCode.DONE_PRE_REFUND.getCode());
        refund.setCreateBy(RestaurantSupport.getCurrentOperationUser());
        restaurantOrderPayRefundService.save(refund);
    }
    
    /**
     * 支付查询
     * @param data
     * @return
     */
    @Override
    public AltoPayQryResult qryPayLog(String data) throws Exception {
        JSONObject json = JSONObject.parseObject(data);
        String out_trade_no = json.getString("out_trade_no");
        RestaurantOrderPay orderPay = new RestaurantOrderPay();
        orderPay.setOutTradeNo(out_trade_no);
        List<RestaurantOrderPay> orderPayList = restaurantOrderPayService.findList(orderPay);
        
        if(null == orderPayList || 0 == orderPayList.size())
        {
            throw new BusinessException("该订单无在线支付记录,请核实!");
        }
    
        orderPay = orderPayList.get(0);
        AltoPayQryMo payQryMo = new AltoPayQryMo();
        payQryMo.setMch_id(orderPay.getMchId());
        payQryMo.setOut_trade_no(orderPay.getOutTradeNo());
        payQryMo.setTrade_no(orderPay.getTradeNo());
        RestaurantPayCfg payCfg = new RestaurantPayCfg();
        payCfg.setRestaurantId(ContextHolder.currentRestaurantId());
        payCfg = this.getCfg(payCfg);
        if(null == payCfg)
        {
            throw new BusinessException("该商户未开通在线支付,请核实!");
        }
        AltoResult result = AltoPayUtils.orderPayQry(payQryMo,payCfg);
        AltoPayQryResult qryResult = (AltoPayQryResult) result.getResult();
        if(null == qryResult)
        {
            throw new BusinessException("未查询到该订单支付情况!");
        }
        return qryResult;
    }
    
    /**
     * 退款查询
     * @param data
     * @return
     */
    @Override
    public AltoRefundQryResult qryRefundLog(String data) throws Exception {
        JSONObject json = JSONObject.parseObject(data);
        String out_trade_no = json.getString("out_trade_no");
        RestaurantOrderPayRefund orderRefund = new RestaurantOrderPayRefund();
        orderRefund.setOutTradeNo(out_trade_no);
        
        List<RestaurantOrderPayRefund> orderRefundList = restaurantOrderPayRefundService.findList(orderRefund);
        if(null == orderRefundList || 0 == orderRefundList.size())
        {
            throw new BusinessException( I18nUtil.getMessage("")+"该订单无在线退款记录,请核实!");
        }
        orderRefund = orderRefundList.get(0);
        
        AltoRefundMo payQryMo = new AltoRefundMo();
        payQryMo.setMch_id(orderRefund.getMchId());
        payQryMo.setOut_trade_no(orderRefund.getOutTradeNo());
        payQryMo.setTrade_no(orderRefund.getTradeNo());
        payQryMo.setOut_refund_no(orderRefund.getOutRefundNo());
        RestaurantPayCfg payCfg = new RestaurantPayCfg();
        payCfg.setRestaurantId(ContextHolder.currentRestaurantId());
        payCfg = this.getCfg(payCfg);
        if(null == payCfg)
        {
            throw new BusinessException("该商户未开通在线支付,请核实!");
        }
        AltoResult result = AltoPayUtils.orderRefund(payQryMo,payCfg);
        AltoRefundQryResult qryResult = (AltoRefundQryResult) result.getResult();
        if(null == qryResult)
        {
            throw new BusinessException("未查询到该订单支付情况!");
        }
        return qryResult;
    }
    
}
